import '../datasources/local/local_data_source.dart';
import '../datasources/remote/note_api_service.dart';
import '../models/note_model.dart' as model;
import '../../core/offline/offline_mode_manager.dart'; // 添加离线模式管理器
import '../../core/offline/offline_data_manager.dart'; // 添加离线数据管理器
import '../../domain/entities/note.dart' as entity;
import '../../domain/entities/note_request.dart' as entity_request;
import '../../domain/repositories/note_repository.dart' as domain_note; // 导入domain层接口

/// 笔记仓储实现
class NoteRepositoryImpl implements domain_note.NoteRepository {
  final NoteApiService _apiService;
  final LocalDataSource _localDataSource;
  final OfflineModeManager _offlineModeManager; // 添加离线模式管理器
  final OfflineDataManager _offlineDataManager; // 添加离线数据管理器

  NoteRepositoryImpl(
    this._apiService,
    this._localDataSource,
    this._offlineModeManager,
    this._offlineDataManager,
  );

  @override
  Future<List<entity.Note>> getNotes({
    int? projectId,
    int? todoId,
    String? keyword,
    List<String>? tags,
    int page = 0,
    int size = 20,
  }) async {
    try {
      // 检查是否处于离线模式
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 从本地数据库获取
        final localNotes = await _localDataSource.getNotes(
          projectId: projectId,
          todoId: todoId,
          keyword: keyword,
          tags: tags,
        );
        return localNotes.map((note) => _mapToEntity(note)).toList();
      }

      // 尝试从API获取数据
      final response = await _apiService.getNotes(
        projectId: projectId,
        todoId: todoId,
        keyword: keyword,
        tags: tags,
        page: page,
        size: size,
      );

      if (response.success && response.data != null) {
        // 保存到本地数据库
        for (final note in response.data!) {
          await _localDataSource.saveNote(note);
        }

        return response.data!.map((note) => _mapToEntity(note)).toList();
      } else {
        // 如果API失败，从本地数据库获取
        final localNotes = await _localDataSource.getNotes(
          projectId: projectId,
          todoId: todoId,
          keyword: keyword,
          tags: tags,
        );
        return localNotes.map((note) => _mapToEntity(note)).toList();
      }
    } catch (e) {
      // 如果API失败，从本地数据库获取
      final localNotes = await _localDataSource.getNotes(
        projectId: projectId,
        todoId: todoId,
        keyword: keyword,
        tags: tags,
      );
      return localNotes.map((note) => _mapToEntity(note)).toList();
    }
  }

  @override
  Future<entity.Note> getNote(int noteId) async {
    try {
      // 检查是否处于离线模式
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 从本地数据库获取
        final localNote = await _localDataSource.findNoteById(noteId);
        if (localNote != null) {
          return _mapToEntity(localNote);
        } else {
          throw Exception('笔记不存在');
        }
      }

      // 尝试从API获取数据
      final response = await _apiService.getNote(noteId);

      if (response.success && response.data != null) {
        // 保存到本地数据库
        await _localDataSource.saveNote(response.data!);

        return _mapToEntity(response.data!);
      } else {
        // 如果API失败，从本地数据库获取
        final localNote = await _localDataSource.findNoteById(noteId);
        if (localNote != null) {
          return _mapToEntity(localNote);
        } else {
          throw Exception('笔记不存在');
        }
      }
    } catch (e) {
      // 如果API失败，从本地数据库获取
      final localNote = await _localDataSource.findNoteById(noteId);
      if (localNote != null) {
        return _mapToEntity(localNote);
      } else {
        rethrow;
      }
    }
  }

  @override
  Future<entity.Note> createNote(
      entity_request.NoteCreateRequest request) async {
    try {
      // 检查是否处于离线模式
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 在离线模式下，保存操作到离线队列
        await _offlineDataManager
            .createNoteOfflineOperation(_mapCreateRequestToModel(request));

        // 创建本地笔记（模拟服务器返回的数据）
        final localNote = model.Note(
          id: DateTime.now().millisecondsSinceEpoch, // 使用时间戳作为临时ID
          title: request.title,
          content: request.content,
          noteType: _mapNoteTypeToModel(request.noteType),
          tags: request.tags,
          authorId: request.authorId,
          isPublic: request.isPublic,
          projectId: request.projectId,
          todoId: request.todoId,
          createTime: DateTime.now(),
          updateTime: DateTime.now(),
        );

        // 保存到本地数据库
        await _localDataSource.saveNote(localNote);

        return _mapToEntity(localNote);
      }

      // 通过API创建笔记
      final response =
          await _apiService.createNote(_mapCreateRequestToModel(request));

      if (response.success && response.data != null) {
        // 保存到本地数据库
        await _localDataSource.saveNote(response.data!);

        return _mapToEntity(response.data!);
      } else {
        throw Exception(response.message ?? '创建笔记失败');
      }
    } catch (e) {
      rethrow;
    }
  }

  @override
  Future<entity.Note> updateNote(
      int noteId, entity_request.NoteUpdateRequest request) async {
    try {
      // 检查是否处于离线模式
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 在离线模式下，保存操作到离线队列
        await _offlineDataManager.updateNoteOfflineOperation(
            noteId, _mapUpdateRequestToModel(request));

        // 更新本地笔记
        final existingNote = await _localDataSource.findNoteById(noteId);
        if (existingNote == null) {
          throw Exception('笔记不存在');
        }

        // 先将现有笔记转换为实体类型，再进行更新
        final existingEntityNote = _mapToEntity(existingNote);
        final updatedEntityNote = existingEntityNote.copyWith(
          title: request.title ?? existingEntityNote.title,
          content: request.content ?? existingEntityNote.content,
          noteType: request.noteType ?? existingEntityNote.noteType,
          tags: request.tags ?? existingEntityNote.tags,
          isPublic: request.isPublic ?? existingEntityNote.isPublic,
          updateTime: DateTime.now(),
        );

        // 保存到本地数据库（需要转换为模型类型）
        await _localDataSource.saveNote(_mapEntityToModel(updatedEntityNote));

        return updatedEntityNote;
      }

      // 通过API更新笔记
      final response = await _apiService.updateNote(
          noteId, _mapUpdateRequestToModel(request));

      if (response.success && response.data != null) {
        // 保存到本地数据库
        await _localDataSource.saveNote(response.data!);

        return _mapToEntity(response.data!);
      } else {
        throw Exception(response.message ?? '更新笔记失败');
      }
    } catch (e) {
      rethrow;
    }
  }

  @override
  Future<void> deleteNote(int noteId) async {
    try {
      // 检查是否处于离线模式
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 在离线模式下，保存操作到离线队列
        await _offlineDataManager.deleteNoteOfflineOperation(noteId);

        // 从本地数据库删除
        await _localDataSource.deleteNote(noteId);
        return;
      }

      // 通过API删除笔记
      final response = await _apiService.deleteNote(noteId);

      if (response.success) {
        // 从本地数据库删除
        await _localDataSource.deleteNote(noteId);
      } else {
        throw Exception(response.message ?? '删除笔记失败');
      }
    } catch (e) {
      rethrow;
    }
  }

  @override
  Future<List<entity.Note>> searchNotes(String keyword) async {
    try {
      // 检查是否处于离线模式
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 从本地数据库搜索
        final localNotes = await _localDataSource.searchNotes(keyword);
        return localNotes.map((note) => _mapToEntity(note)).toList();
      }

      // 通过API搜索
      final response = await _apiService.searchNotes(keyword);

      if (response.success && response.data != null) {
        // 保存到本地数据库
        for (final note in response.data!) {
          await _localDataSource.saveNote(note);
        }

        return response.data!.map((note) => _mapToEntity(note)).toList();
      } else {
        // 如果API失败，从本地数据库搜索
        final localNotes = await _localDataSource.searchNotes(keyword);
        return localNotes.map((note) => _mapToEntity(note)).toList();
      }
    } catch (e) {
      // 如果API失败，从本地数据库搜索
      final localNotes = await _localDataSource.searchNotes(keyword);
      return localNotes.map((note) => _mapToEntity(note)).toList();
    }
  }

  @override
  Future<List<entity.Note>> getNotesByTags(List<String> tags) async {
    try {
      // 检查是否处于离线模式
      if (_offlineModeManager.canPerformOfflineOperation()) {
        // 从本地数据库获取
        final localNotes = await _localDataSource.getNotesByTags(tags);
        return localNotes.map((note) => _mapToEntity(note)).toList();
      }

      // 通过API获取
      final response = await _apiService.getNotesByTags(tags);

      if (response.success && response.data != null) {
        // 保存到本地数据库
        for (final note in response.data!) {
          await _localDataSource.saveNote(note);
        }

        return response.data!.map((note) => _mapToEntity(note)).toList();
      } else {
        // 如果API失败，从本地数据库获取
        final localNotes = await _localDataSource.getNotesByTags(tags);
        return localNotes.map((note) => _mapToEntity(note)).toList();
      }
    } catch (e) {
      // 如果API失败，从本地数据库获取
      final localNotes = await _localDataSource.getNotesByTags(tags);
      return localNotes.map((note) => _mapToEntity(note)).toList();
    }
  }

  /// 将实体创建请求映射到模型创建请求
  model.NoteCreateRequest _mapCreateRequestToModel(
      entity_request.NoteCreateRequest request) {
    return model.NoteCreateRequest(
      projectId: request.projectId,
      todoId: request.todoId,
      title: request.title,
      content: request.content,
      noteType: _mapNoteTypeToModel(request.noteType),
      tags: request.tags,
      authorId: request.authorId,
      isPublic: request.isPublic,
    );
  }

  /// 将实体更新请求映射到模型更新请求
  model.NoteUpdateRequest _mapUpdateRequestToModel(
      entity_request.NoteUpdateRequest request) {
    return model.NoteUpdateRequest(
      title: request.title,
      content: request.content,
      noteType: request.noteType != null
          ? _mapNoteTypeToModel(request.noteType!)
          : null,
      tags: request.tags,
      isPublic: request.isPublic,
    );
  }

  /// 将模型笔记类型映射到实体笔记类型
  entity.NoteType _mapNoteTypeToEntity(model.NoteType noteType) {
    switch (noteType) {
      case model.NoteType.general:
        return entity.NoteType.general;
      case model.NoteType.meeting:
        return entity.NoteType.meeting;
      case model.NoteType.solution:
        return entity.NoteType.solution;
      case model.NoteType.issue:
        return entity.NoteType.issue;
    }
  }

  /// 将实体笔记类型映射到模型笔记类型
  model.NoteType _mapNoteTypeToModel(entity.NoteType noteType) {
    switch (noteType) {
      case entity.NoteType.general:
        return model.NoteType.general;
      case entity.NoteType.meeting:
        return model.NoteType.meeting;
      case entity.NoteType.solution:
        return model.NoteType.solution;
      case entity.NoteType.issue:
        return model.NoteType.issue;
    }
  }

  /// 将实体转换为模型
  model.Note _mapEntityToModel(entity.Note entity) {
    return model.Note(
      id: entity.id,
      projectId: entity.projectId,
      todoId: entity.todoId,
      title: entity.title,
      content: entity.content,
      noteType: _mapNoteTypeToModel(entity.noteType),
      tags: entity.tags,
      authorId: entity.authorId,
      isPublic: entity.isPublic,
      createTime: entity.createTime,
      updateTime: entity.updateTime,
    );
  }

  /// 将模型转换为实体
  entity.Note _mapToEntity(model.Note model) {
    return entity.Note(
      id: model.id,
      projectId: model.projectId,
      todoId: model.todoId,
      title: model.title,
      content: model.content,
      noteType: _mapNoteTypeToEntity(model.noteType),
      tags: model.tags,
      authorId: model.authorId,
      isPublic: model.isPublic,
      createTime: model.createTime,
      updateTime: model.updateTime,
    );
  }
}